import React, { useState } from 'react';
import { 
  Button, 
  Dialog, 
  DialogTitle, 
  DialogContent, 
  DialogActions,
  Menu,
  MenuItem,
  CircularProgress,
  Typography,
  Box,
  Alert
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useMutation, useQueryClient } from 'react-query';
import { RemoveCreditCard, SetDefaultCreditCard, CancelSubscription, CreateCustomerPortalSession } from 'api/mutations';
import { ENABLE_CUSTOMER_PORTAL } from 'config';

import CreditCardIcon from '@mui/icons-material/CreditCard';
import DeleteIcon from '@mui/icons-material/Delete';
import StarIcon from '@mui/icons-material/Star';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import SubscriptionsIcon from '@mui/icons-material/Subscriptions';
import CancelIcon from '@mui/icons-material/Cancel';
import PaymentIcon from '@mui/icons-material/Payment';
import SyncIcon from '@mui/icons-material/Sync';
import ReceiptLongIcon from '@mui/icons-material/ReceiptLong';
import LaunchIcon from '@mui/icons-material/Launch';
import AttachMoneyIcon from '@mui/icons-material/AttachMoney';

const ReusableButton = ({ 
  buttonType = 'base',
  actionType = 'navigate',
  navigateTo,
  params = {},
  label,
  icon,
  onAction,
  primaryAction = true,
  secondaryAction = false,
  onStateChange,
  menuItems = [],
  dialogContent = {
    title: "",
    message: "",
    confirmLabel: "Confirm",
    cancelLabel: "Cancel"
  },
  variant = "contained", 
  color = "primary", 
  fullWidth = true, 
  size = "medium",
  disabled = false,
  cardId,
  isDefault = false,
  hasMultipleCards = true,
  subscriptionId,
  isCanceled = false,
  invoiceId,
  hostedUrl,
  isPaid = false,
  ...props 
}) => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const [success, setSuccess] = useState(null);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [menuAnchor, setMenuAnchor] = useState(null);

  const removeCardMutation = useMutation(RemoveCreditCard, {
    onSuccess: () => {
      queryClient.invalidateQueries(["CustomerCards"]);
    }
  });

  const setDefaultCardMutation = useMutation(SetDefaultCreditCard, {
    onSuccess: () => {
      queryClient.invalidateQueries(["Customer"]);
    }
  });

  const cancelSubscriptionMutation = useMutation(CancelSubscription, {
    onSuccess: () => {
      queryClient.invalidateQueries(["Customer"]);
    }
  });

  const customerPortalMutation = useMutation(CreateCustomerPortalSession, {});

  const handleCustomerPortal = async () => {
    const response = await customerPortalMutation.mutateAsync();
    window.location.href = response.data.redirect_url;
    return { message: t("subscriptionActions.redirectingToPortal") };
  };

  const handleOpenHostedUrl = () => {
    if (hostedUrl) {
      window.open(hostedUrl, '_blank', 'noopener,noreferrer');
      return { message: t("paymentActions.openingInvoice") };
    }
    throw new Error(t("paymentActions.noUrlAvailable"));
  };

  let buttonProps = {};

  if (buttonType === 'card') {
    switch (actionType) {
      case 'view':
        buttonProps = {
          label: label || t("cardActions.viewCards"),
          icon: icon || <CreditCardIcon />,
          actionType: "navigate",
          navigateTo: "/payment-methods",
          color: color,
          variant: variant,
        };
        break;
      case 'remove':
        buttonProps = {
          label: label || t("cardActions.removeCard"),
          icon: icon || <DeleteIcon />,
          actionType: "dialog",
          params: { cardId },
          onAction: (params) => removeCardMutation.mutateAsync({ cardId: params.cardId }),
          dialogContent: dialogContent || {
            title: t("cardActions.removeCard"),
            message: t("cardActions.removeCardConfirmation"),
            confirmLabel: t("cardActions.confirm"),
            cancelLabel: t("common.cancel")
          },
          disabled: isDefault && !hasMultipleCards,
          color: color || "error",
          variant: variant,
        };
        break;
      case 'setDefault':
        buttonProps = {
          label: label || t("cardActions.setDefault"),
          icon: icon || <StarIcon />,
          actionType: "dialog",
          params: { cardId },
          onAction: (params) => setDefaultCardMutation.mutateAsync({ cardId: params.cardId }),
          dialogContent: dialogContent || {
            title: t("cardActions.setDefaultCard"),
            message: t("cardActions.setDefaultCardConfirmation"),
            confirmLabel: t("cardActions.confirm"),
            cancelLabel: t("common.cancel")
          },
          disabled: isDefault,
          color: color,
          variant: variant,
        };
        break;
      case 'menu':
        buttonProps = {
          label: label || t("cardActions.actions"),
          icon: icon || <MoreVertIcon />,
          actionType: "menu",
          params: { cardId },
          menuItems: menuItems.length ? menuItems : [
            {
              label: t("cardActions.setDefault"),
              icon: <StarIcon />,
              action: () => setDefaultCardMutation.mutate({ cardId }),
              disabled: isDefault
            },
            {
              label: t("cardActions.removeCard"),
              icon: <DeleteIcon />,
              action: () => removeCardMutation.mutate({ cardId }),
              disabled: isDefault && !hasMultipleCards
            }
          ],
          color: color,
          variant: variant,
        };
        break;
      default:
        buttonProps = {
          label: label || t("cardActions.viewCards"),
          icon: icon || <CreditCardIcon />,
          actionType: "navigate",
          navigateTo: "/payment-methods",
          color: color,
          variant: variant,
        };
    }
  } else if (buttonType === 'subscription') {
    switch (actionType) {
      case 'view':
        buttonProps = {
          label: label || t("subscriptionActions.viewSubscription"),
          icon: icon || <SubscriptionsIcon />,
          actionType: "navigate",
          navigateTo: "/subscription",
          color: color,
          variant: variant,
        };
        break;
      case 'cancel':
        buttonProps = {
          label: label || t("subscriptionActions.cancelSubscription"),
          icon: icon || <CancelIcon />,
          actionType: ENABLE_CUSTOMER_PORTAL ? "function" : "dialog",
          params: { subscriptionId },
          onAction: ENABLE_CUSTOMER_PORTAL 
            ? handleCustomerPortal
            : (params) => cancelSubscriptionMutation.mutateAsync({ subscriptionId: params.subscriptionId }),
          dialogContent: dialogContent || {
            title: t("subscriptionActions.cancelSubscription"),
            message: t("subscriptionActions.cancelConfirmation"),
            confirmLabel: t("subscriptionActions.confirm"),
            cancelLabel: t("common.cancel")
          },
          disabled: isCanceled || !subscriptionId,
          color: color || "error",
          variant: variant,
        };
        break;
      case 'changePlan':
        buttonProps = {
          label: label || t("subscriptionActions.changePlan"),
          icon: icon || <SyncIcon />,
          actionType: "navigate",
          navigateTo: "/plan",
          color: color,
          variant: variant,
        };
        break;
      case 'portal':
        buttonProps = {
          label: label || t("subscriptionActions.customerPortal"),
          icon: icon || <PaymentIcon />,
          actionType: "function",
          onAction: handleCustomerPortal,
          color: color,
          variant: variant,
        };
        break;
      default:
        buttonProps = {
          label: label || t("subscriptionActions.viewSubscription"),
          icon: icon || <SubscriptionsIcon />,
          actionType: "navigate",
          navigateTo: "/subscription",
          color: color,
          variant: variant,
        };
    }
  } else if (buttonType === 'payment') {
    switch (actionType) {
      case 'view':
        buttonProps = {
          label: label || t("paymentActions.viewHistory"),
          icon: icon || <ReceiptLongIcon />,
          actionType: "navigate",
          navigateTo: "/payment-history",
          color: color,
          variant: variant,
        };
        break;
      case 'pay':
        buttonProps = {
          label: label || t("paymentActions.payInvoice"),
          icon: icon || <AttachMoneyIcon />,
          actionType: "function",
          params: { invoiceId, hostedUrl },
          onAction: handleOpenHostedUrl,
          disabled: isPaid || !hostedUrl,
          color: color,
          variant: variant,
        };
        break;
      case 'details':
        buttonProps = {
          label: label || t("paymentActions.viewDetails"),
          icon: icon || <LaunchIcon />,
          actionType: "navigate",
          navigateTo: `/payment-history/${invoiceId}`,
          color: color,
          variant: variant,
        };
        break;
      case 'menu':
        buttonProps = {
          label: label || t("paymentActions.actions"),
          icon: icon || <MoreVertIcon />,
          actionType: "menu",
          params: { invoiceId, hostedUrl },
          menuItems: menuItems.length ? menuItems : [
            {
              label: t("paymentActions.viewDetails"),
              icon: <LaunchIcon />,
              action: () => window.location.href = `/payment-history/${invoiceId}`,
            },
            {
              label: t("paymentActions.payInvoice"),
              icon: <AttachMoneyIcon />,
              action: handleOpenHostedUrl,
              disabled: isPaid || !hostedUrl
            }
          ],
          color: color,
          variant: variant,
        };
        break;
      default:
        buttonProps = {
          label: label || t("paymentActions.viewHistory"),
          icon: icon || <ReceiptLongIcon />,
          actionType: "navigate",
          navigateTo: "/payment-history",
          color: color,
          variant: variant,
        };
    }
  } else {
    buttonProps = {
      label: label || "Action",
      icon: icon,
      actionType: actionType,
      navigateTo: navigateTo,
      params: params,
      onAction: onAction,
      dialogContent: dialogContent,
      menuItems: menuItems,
      color: color,
      variant: variant,
    };
  }

  const handleClick = (event) => {
    if (buttonProps.actionType === 'navigate' && buttonProps.navigateTo) {
      navigate(buttonProps.navigateTo);
    } else if (buttonProps.actionType === 'dialog') {
      setDialogOpen(true);
    } else if (buttonProps.actionType === 'menu') {
      setMenuAnchor(event.currentTarget);
    } else if (buttonProps.actionType === 'function' && (buttonProps.onAction || onAction)) {
      handleAction();
    }

    if (secondaryAction && onStateChange) {
      onStateChange({ triggered: true, params: buttonProps.params || params });
    }
  };

  const handleAction = async () => {
    const actionFn = buttonProps.onAction || onAction;
    if (!actionFn) return;
    
    setIsLoading(true);
    setError(null);
    setSuccess(null);
    
    try {
      const result = await actionFn(buttonProps.params || params);
      setSuccess(result?.message || t('common.actionSuccessful'));
      
      if (secondaryAction && onStateChange) {
        onStateChange({ triggered: true, success: true, result, params: buttonProps.params || params });
      }
      
      if (dialogOpen) {
        setDialogOpen(false);
      }
    } catch (err) {
      setError(err?.message || t('common.actionFailed'));
      
      if (secondaryAction && onStateChange) {
        onStateChange({ triggered: true, success: false, error: err, params: buttonProps.params || params });
      }
    } finally {
      setIsLoading(false);
    }
  };

  const handleDialogConfirm = () => {
    handleAction();
  };

  const handleDialogCancel = () => {
    setDialogOpen(false);
    
    if (secondaryAction && onStateChange) {
      onStateChange({ triggered: false, canceled: true, params: buttonProps.params || params });
    }
  };

  const handleMenuItemClick = (item) => {
    setMenuAnchor(null);
    
    if (item.action) {
      item.action(buttonProps.params || params);
    }
    
    if (secondaryAction && onStateChange) {
      onStateChange({ triggered: true, menuItem: item, params: buttonProps.params || params });
    }
  };

  const handleMenuClose = () => {
    setMenuAnchor(null);
  };

  return (
    <>
      <Button
        variant={buttonProps.variant || variant}
        color={buttonProps.color || color}
        fullWidth={fullWidth}
        size={size}
        disabled={buttonProps.disabled || disabled || isLoading}
        startIcon={isLoading ? null : (buttonProps.icon || icon)}
        onClick={handleClick}
        {...props}
      >
        {isLoading ? <CircularProgress size={24} color="inherit" /> : (buttonProps.label || label)}
      </Button>
      
      {error && (
        <Box mt={1}>
          <Alert severity="error" onClose={() => setError(null)}>
            {error}
          </Alert>
        </Box>
      )}
      
      {success && (
        <Box mt={1}>
          <Alert severity="success" onClose={() => setSuccess(null)}>
            {success}
          </Alert>
        </Box>
      )}
      
      <Dialog open={dialogOpen} onClose={handleDialogCancel}>
        <DialogTitle>{buttonProps.dialogContent?.title || dialogContent.title}</DialogTitle>
        <DialogContent>
          <Typography>
            {buttonProps.dialogContent?.message || dialogContent.message}
          </Typography>
          {buttonProps.dialogContent?.content || dialogContent.content}
        </DialogContent>
        <DialogActions>
          <Button onClick={handleDialogCancel}>
            {buttonProps.dialogContent?.cancelLabel || dialogContent.cancelLabel}
          </Button>
          <Button 
            onClick={handleDialogConfirm} 
            color={buttonProps.color || color}
            disabled={isLoading}
          >
            {isLoading ? 
              <CircularProgress size={24} /> : 
              (buttonProps.dialogContent?.confirmLabel || dialogContent.confirmLabel)
            }
          </Button>
        </DialogActions>
      </Dialog>
      
      <Menu
        anchorEl={menuAnchor}
        open={Boolean(menuAnchor)}
        onClose={handleMenuClose}
      >
        {(buttonProps.menuItems || menuItems).map((item, index) => (
          <MenuItem 
            key={`menu-item-${index}`}
            onClick={() => handleMenuItemClick(item)}
            disabled={item.disabled}
          >
            {item.icon && (
              <Box component="span" mr={1} display="flex" alignItems="center">
                {item.icon}
              </Box>
            )}
            {item.label}
          </MenuItem>
        ))}
      </Menu>
    </>
  );
};

export const CardButton = (props) => {
  return <ReusableButton buttonType="card" {...props} />;
};

export const SubscriptionButton = (props) => {
  return <ReusableButton buttonType="subscription" {...props} />;
};

export const PaymentButton = (props) => {
  return <ReusableButton buttonType="payment" {...props} />;
};

export default ReusableButton;